package org.ponly.cta4j.drawing;

import java.awt.Font;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.text.AttributedString;

/**
 * 抽象 Painter.
 *
 * @author vacoor
 * @since 1.0
 */
public abstract class AbstractPainter implements Painter {

    /**
     * {@inheritDoc}
     */
    @Override
    public BufferedImage paint(final BufferedImage canvas, final String text) {
        final int length = checkTextLength(text);
        final AttributedString attributedString = getAttributedString(text, length);

        return doPaintText(doPaintBackground(canvas), attributedString);
    }

    /**
     * 在给定的画布上绘制背景.
     *
     * @param canvas 画布
     * @return 绘制好完背景的内容
     */
    protected abstract BufferedImage doPaintBackground(final BufferedImage canvas);

    /**
     * 给给定的画布上绘制样式文本信息.
     *
     * @param canvas           画布
     * @param attributedString 样式文本
     * @return 绘制好文本的内容
     */
    protected abstract BufferedImage doPaintText(final BufferedImage canvas, final AttributedString attributedString);

    /**
     * 校验文本长度是否合法并返回合法的长度.
     *
     * @param text 文本内容
     * @return 合法长度
     */
    protected int checkTextLength(final String text) {
        // TODO
        if (null == text) {
            throw new IllegalStateException("null text");
        }

        final int length = text.length();
        final int minLength = getMinTextLength();
        final int maxLength = getMaxTextLength();

        if (length > maxLength || length < minLength) {
            throw new IllegalArgumentException("invalid length text");
        }
        return length;
    }

    /**
     * 获取当前文本的风格化字符串.
     *
     * @param text      文本内容
     * @param maxLength 最大长度
     * @return 对应的风格化字符串
     */
    protected AttributedString getAttributedString(final String text, final int maxLength) {
        final AttributedString attributedString = new AttributedString(text);

        for (int i = 0; i < maxLength; i++) {
            final Font font = getFont();
            attributedString.addAttribute(TextAttribute.FONT, font, i, i + 1);
        }
        return attributedString;
    }

    /**
     * 获取一个随机字体.
     *
     * @return 字体
     */
    protected abstract Font getFont();

}
